package com.ruoyi.web.sso.service.impl;

import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.google.gson.Gson;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.web.sso.service.OssService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;

/**
 * 能力指标Service业务层处理
 *
 * @author qiufeng
 * @date 2022-03-10
 */
@Service
public class OssServiceImpl implements OssService
{
    //测试地址
    @Value("${oss.endpoint}")
    private String endpoint;
    @Value("${oss.accessKeyId}")
    private String accessKeyId;
    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;
    @Value("${oss.bucketName}")
    private String bucketName;
    @Value("${oss.url}")
    public  String url;
    @Value("${oss.path}")
    public  String path;

    public String aliyunOssUpload(String relativePath, MultipartFile file) {
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            if (!ossClient.doesBucketExist(bucketName)) {
                /*
                 * Create a new OSS bucket
                 */
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest= new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }

            ossClient.putObject(new PutObjectRequest(bucketName, relativePath, file.getInputStream()));
            ossClient.setObjectAcl(bucketName, relativePath, CannedAccessControlList.PublicRead);
            ossClient.setObjectAcl(bucketName, relativePath, CannedAccessControlList.Default);

        } catch (OSSException oe) {

        } catch (ClientException ce) {

        } catch (IOException ie){

        } finally{
            ossClient.shutdown();
        }
        return relativePath;
    }

    public String aliyunOssUpload(String relativePath, File file) {
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            if (!ossClient.doesBucketExist(bucketName)) {
                /*
                 * Create a new OSS bucket
                 */
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest= new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }

            ossClient.putObject(new PutObjectRequest(bucketName, relativePath, file));
            ossClient.setObjectAcl(bucketName, relativePath, CannedAccessControlList.PublicRead);
            ossClient.setObjectAcl(bucketName, relativePath, CannedAccessControlList.Default);

        } catch (OSSException oe) {

        } catch (ClientException ce) {

        }finally{
            ossClient.shutdown();
        }
        return relativePath;
    }

    public void aliyunOssDelete(String relativePath) {
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        ossClient.deleteObject(bucketName, relativePath);
    }

    public void aliyunOssCopy() {
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        CopyObjectRequest copyObjectRequest = new CopyObjectRequest("", "", "", "");
    }


    public static  Date addDay(Date date ,int day){
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        // 把日期往后增加一天,整数  往后推,负数往前移动
        calendar.add(Calendar.DATE, day);
        // 这个时间就是日期往后推一天的结果
        return  calendar.getTime();
    }

    /**
     * 获取出生到现在多少天
     *
     * @param date  当前日期
     * @param date1 生日
     * @return
     */
    public static int birthdayDay(Date date, Date date1) {
        long betweenDays = (date.getTime() - date1.getTime()) / (1000L*3600L*24L);
        return (int) Math.abs(betweenDays);
    }

    public static void main(String[] args) throws Throwable {
        // 以华东1（杭州）的外网Endpoint为例，其它Region请按实际情况填写。
        String endpoint = "oss-cn-shanghai.aliyuncs.com";
        // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
        String accessKeyId = "LTAI5tRU1w4C1npBtMrTwyd8";
        String accessKeySecret = "N4PUolI5CRU6K380BnsqTNULnbzrF9";
        // 填写Bucket名称，例如examplebucket。
        String bucketName = "dotflat-saas-res";
        // 填写Object完整路径，例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
        String objectName = "https://saas.res.dotflat.cn/sso/area/exampleobject.txt";
        // 填写本地文件的完整路径。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。

        AssumeRoleResponse  response =  getOssRoleResponse(endpoint,accessKeyId,accessKeySecret,"","",3600L);

        String securityToken = response.getCredentials().getSecurityToken();

        System.out.println(securityToken);

    }

    public URL getOssTemporarySignature(String objectName){
        // 从STS服务获取临时访问凭证后，您可以通过临时访问密钥和安全令牌生成OSSClient（既这里的accessKeyId和accessKeySecret为STS服务返回的）。
        // 使用STS服务创建OSSClient实例。
        String securityToken = "9000";
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);

        // 设置请求头。
        Map<String, String> headers = new HashMap<String, String>();

        // 设置用户自定义元信息。
        Map<String, String> userMetadata = new HashMap<String, String>();
        /*userMetadata.put("key1","value1");
        userMetadata.put("key2","value2");*/

        URL signedUrl = null;
        try {
            // 指定生成的签名URL过期时间，单位为毫秒。
            Date expiration = new Date(new Date().getTime() + 3600 * 1000);

            // 生成签名URL。
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
            // 设置过期时间。
            request.setExpiration(expiration);

            // 将请求头加入到request中。
            request.setHeaders(headers);
            // 添加用户自定义元信息。
            request.setUserMetadata(userMetadata);

            // 通过HTTP PUT请求生成签名URL。
            signedUrl = ossClient.generatePresignedUrl(request);
            // 打印签名URL。
//            System.out.println("signed url for putObject: " + signedUrl);
        } catch (OSSException oe) {
            System.out.println("Error Message:" + oe.getErrorMessage());
        } catch (Exception ce) {
            System.out.println("Error Message:" + ce.getMessage());
        }
        return  signedUrl;
    }

    /**
     * @param roleArn 角色ARN。 * @param roleSessionName 自定义角色会话名称
     * @param endpoint
     * @param accessKeyId
     * @param accessKeySecret
     * @param roleArn
     * @param expired
     * @return
     */
    private  static AssumeRoleResponse getOssRoleResponse(String endpoint,String accessKeyId,String accessKeySecret,String roleArn,String roleSessionName,long expired ) {

        try {
            // 添加endpoint（直接使用STS endpoint，前两个参数留空，无需添加region ID）
            DefaultProfile.addEndpoint("", "", "Sts", endpoint);
            // 构造default profile（参数留空，无需添加region ID）
            IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
            // 用profile构造client
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setMethod(MethodType.POST);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setDurationSeconds( expired ); // 设置凭证有效时间
            final AssumeRoleResponse response = client.getAcsResponse(request);
            return response;
        } catch (Exception e) {
        }
        return null;
    }

}
